package com.idea.dsl.validator;

import com.idea.dsl.model.DslResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * SQL DSL验证器
 */
@Slf4j
@Component
public class SqlDslValidator implements DslValidator {
    
    // SQL关键字模式
    private static final Pattern SQL_KEYWORDS = Pattern.compile(
        "(?i)\\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|TRUNCATE|FROM|WHERE|JOIN|GROUP|ORDER|HAVING)\\b"
    );
    
    // SQL注释模式
    private static final Pattern SQL_COMMENTS = Pattern.compile("--.*|/\\*[\\s\\S]*?\\*/");
    
    @Override
    public DslResponse.ValidationResult validate(String dslContent, String dslType) {
        List<String> errors = new ArrayList<>();
        List<String> warnings = new ArrayList<>();
        boolean syntaxValid = true;
        boolean semanticValid = true;
        
        try {
            // 基本语法验证
            syntaxValid = validateSqlSyntax(dslContent, errors, warnings);
            
            // 语义验证
            if (syntaxValid) {
                semanticValid = validateSqlSemantics(dslContent, errors, warnings);
            }
            
            log.debug("SQL验证完成: syntaxValid={}, semanticValid={}", syntaxValid, semanticValid);
            
        } catch (Exception e) {
            syntaxValid = false;
            errors.add("SQL验证异常: " + e.getMessage());
            log.warn("SQL验证失败: {}", e.getMessage());
        }
        
        boolean valid = syntaxValid && semanticValid && errors.isEmpty();
        
        return DslResponse.ValidationResult.builder()
                .valid(valid)
                .errors(errors)
                .warnings(warnings)
                .syntaxValid(syntaxValid)
                .semanticValid(semanticValid)
                .build();
    }
    
    private boolean validateSqlSyntax(String sql, List<String> errors, List<String> warnings) {
        if (sql == null || sql.trim().isEmpty()) {
            errors.add("SQL内容为空");
            return false;
        }
        
        String cleanSql = sql.trim();
        
        // 检查是否包含SQL关键字
        if (!SQL_KEYWORDS.matcher(cleanSql).find()) {
            warnings.add("未检测到SQL关键字，可能不是有效的SQL语句");
        }
        
        // 检查基本的括号匹配
        if (!isParenthesesBalanced(cleanSql)) {
            errors.add("括号不匹配");
            return false;
        }
        
        // 检查分号结尾（对于某些SQL语句）
        if (cleanSql.toLowerCase().startsWith("create") || 
            cleanSql.toLowerCase().startsWith("insert") ||
            cleanSql.toLowerCase().startsWith("update") ||
            cleanSql.toLowerCase().startsWith("delete")) {
            if (!cleanSql.endsWith(";")) {
                warnings.add("建议在SQL语句末尾添加分号");
            }
        }
        
        return true;
    }
    
    private boolean validateSqlSemantics(String sql, List<String> errors, List<String> warnings) {
        String lowerSql = sql.toLowerCase().trim();
        
        // 检查SELECT语句的基本结构
        if (lowerSql.startsWith("select")) {
            if (!lowerSql.contains("from") && !lowerSql.contains("dual")) {
                warnings.add("SELECT语句通常需要FROM子句");
            }
        }
        
        // 检查INSERT语句的基本结构
        if (lowerSql.startsWith("insert")) {
            if (!lowerSql.contains("into")) {
                errors.add("INSERT语句缺少INTO关键字");
                return false;
            }
            if (!lowerSql.contains("values") && !lowerSql.contains("select")) {
                errors.add("INSERT语句缺少VALUES或SELECT子句");
                return false;
            }
        }
        
        // 检查UPDATE语句的基本结构
        if (lowerSql.startsWith("update")) {
            if (!lowerSql.contains("set")) {
                errors.add("UPDATE语句缺少SET关键字");
                return false;
            }
        }
        
        // 检查CREATE TABLE语句的基本结构
        if (lowerSql.startsWith("create table")) {
            if (!sql.contains("(") || !sql.contains(")")) {
                errors.add("CREATE TABLE语句缺少列定义");
                return false;
            }
        }
        
        return true;
    }
    
    private boolean isParenthesesBalanced(String sql) {
        int count = 0;
        for (char c : sql.toCharArray()) {
            if (c == '(') {
                count++;
            } else if (c == ')') {
                count--;
                if (count < 0) {
                    return false;
                }
            }
        }
        return count == 0;
    }
    
    @Override
    public String getSupportedDslType() {
        return "sql";
    }
    
    @Override
    public boolean supports(String dslType) {
        return "sql".equalsIgnoreCase(dslType);
    }
}
